package com.lingxu.traffic.controller;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lingxu.api.ztb.service.IZtbProjectService;
import com.lingxu.base.common.api.vo.Result;
import com.lingxu.base.system.manage.entity.SysUser;
import com.lingxu.base.system.manage.mapper.SysUserMapper;
import com.lingxu.module.collection.entity.ModelColumnInfo;
import com.lingxu.module.collection.mapper.ReportMapper;
import com.lingxu.module.database.entity.ModelRun;
import com.lingxu.module.earlyWarn.entity.IssueManage;
import com.lingxu.module.earlyWarn.mapper.IssueManageMapper;
import com.lingxu.module.process.CheckVariable;
import com.lingxu.module.process.controller.vo.IssmcVO;
import com.lingxu.module.process.controller.vo.ModelVO;
import com.lingxu.module.process.mapper.CommonMapper;
import com.lingxu.module.process.mapper.ModelRunRecordMapper;
import com.lingxu.module.process.model.TModelActivity;
import com.lingxu.module.process.service.ITModelActivityService;
import com.lingxu.module.risk.entity.ModelRunVo;
import com.lingxu.module.risk.entity.TModelRunRecord;
import com.lingxu.module.risk.mapper.TModelRunRecordMapper;
import com.lingxu.module.risk.service.RiskService;
import com.lingxu.module.risk.service.impl.RiskServiceImpl;
import com.lingxu.traffic.dto.ProjectOverviewDTO;
import com.lingxu.traffic.service.ProjectService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.lingxu.module.risk.service.impl.RiskServiceImpl.groupRule;
import static jdk.nashorn.internal.runtime.JSType.toNumber;

/**
 * @ClassName TrafficController
 * @Description 描述
 * @Author junyi.wang
 * @Date 2025/7/3 16:21
 */
@RestController
@RequestMapping(value = "/traffic")
public class ProjectOverviewController {
    @Autowired
    private ITModelActivityService tModelActivityService;
    @Autowired
    private CommonMapper commonMapper;

    @Autowired
    private ModelRunRecordMapper modelRunRecordMapper;

    @Autowired
    private IssueManageMapper issueManageMapper;
    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private ProjectService projectService;

    @Autowired
    private IZtbProjectService iZtbProjectService;

    @Autowired
    private RiskService riskService;

    @Resource
    private  TModelRunRecordMapper tModelRunRecordMapper;

    @Resource
    private  ReportMapper reportMapper;

    @Resource
    private RiskServiceImpl riskServiceImpl;

    @GetMapping("/comprehensive")
    public Result<Map<String, Object>> getComprehensiveStatistics() {
        Map<String, Object> result = new HashMap<>();

        Integer basicStats = projectService.getProjectStatistics();
        result.put("项目总数", basicStats);
       /* result.put("人员总数", basicStats.get("RYZS"));
        result.put("设备总数", basicStats.get("SBZS"));*/

      /*  // 2. 年度投资
        BigDecimal yearInvestment = projectService.getTotalYearInvestment();
        result.put("年度投资", yearInvestment);*/

        // 3. 整体进度
       /* BigDecimal averageProgress = projectService.calculateAverageProgress();
        result.put("整体进度", averageProgress);*/

      /*  // 4. 参建单位数量
        Integer participantUnitCount = projectService.getParticipantCount();
        result.put("参建单位数量", participantUnitCount);*/

        return Result.ok(result);
    }


    @ApiOperation(value="当前预警数")
    @GetMapping("/IssNum")
    public Result<Map<String, Object>> getIssNum(String userId) {
        Map<String, Object> result = new HashMap<>();
        result.put("当前预警数", projectService.getIssNum(userId));
        return Result.ok(result);
    }
    @ApiOperation(value="预警信息相关名称")
    @GetMapping("/Issmc")
    public Result<Map<String, Object>> getIssmc(String userId) {
        IssmcVO issmc = projectService.getIssmc(userId);
        Map<String, Object> result = new HashMap<>();
        result.put("预警规则", issmc.getName());//模型名称

        //根据模型id查询最新运行记录中的结果表
        LambdaQueryWrapper<ModelRun> runWrapper = new LambdaQueryWrapper<>();
        runWrapper.eq(ModelRun::getModelid, issmc.getId())
                .eq(ModelRun::getRunstatus, "01")
                .orderByDesc(ModelRun::getStarttime)
                .last("LIMIT 1");
        ModelRun modelRun = modelRunRecordMapper.selectOne(runWrapper);

        if (modelRun != null && modelRun.getResulttable() != null) {
            String resultTable = modelRun.getResulttable().toUpperCase();
            String schemaName = "DIMENRESULT";

            // 1. 查询包含PROJECTNAME的字段名
            List<String> projectColumns = commonMapper.queryProjectColumns(
                    schemaName, resultTable, "%PROJECTNAME%"
            );

            if (!projectColumns.isEmpty()) {
                // 2. 拼接字段名，查询前3条数据
                String columns = String.join(", ", projectColumns);
                List<Map<String, Object>> projectData = commonMapper.queryProjectData(
                        schemaName, resultTable, columns
                );
                result.put("项目信息", projectData);
                if (!projectData.isEmpty() && projectData.get(0).containsKey(projectColumns.get(0))) {
                    result.put("项目名称", projectData.get(0).get(projectColumns.get(0)));
                } else {
                    result.put("项目名称", "无数据");
                }
            } else {
                result.put("项目信息", "未找到包含PROJECTNAME的字段");
                result.put("项目名称", "未找到相关字段");
            }
        } else {
            result.put("项目信息", "未查询到模型运行记录或结果表");
            result.put("项目名称", "无结果表信息");
        }

        return Result.ok(result);

    }

    @PostMapping(value = "/queryModelNewInfo")
    public Result queryModelNewInfo(@RequestBody ModelVO modelVO) {
        List<ModelVO> dataForYJ = tModelActivityService.getDataForYJ(modelVO);
        List<Map<String, Object>> modelList = new ArrayList<>();

        for (ModelVO vo : dataForYJ) {
            Map<String, Object> modelInfo = new HashMap<>();
            modelInfo.put("id",vo.getId()); //模型id
            modelInfo.put("modelType", vo.getCateName()); // 模型类别
            modelInfo.put("modelName", vo.getName());     // 预警名称
            modelInfo.put("modelStatus", vo.getRwstatus()); // 预警状态

            Integer result = getResult(vo.getId());

            modelInfo.put("modelNum", result); // 问题数量
            modelInfo.put("modelName",vo.getModelName());
            modelInfo.put("updateTime",vo.getUPDATETIME());
            modelInfo.put("remark",vo.getRemark());
//            modelInfo.put("creatorName",vo.getCreatorName());
            modelInfo.put("name",vo.getCreatorName());
            modelList.add(modelInfo);

            modelList.sort((map1, map2) -> {
                Integer num1 = (Integer) map1.get("modelNum");
                Integer num2 = (Integer) map2.get("modelNum");
                // 处理null值（默认null视为0，避免空指针）
                num1 = num1 == null ? 0 : num1;
                num2 = num2 == null ? 0 : num2;
                return Integer.compare(num2, num1); // 降序：后减前
            });
        }
        return Result.ok(modelList);
    }

    @ApiOperation(value="预警模型信息")
    @PostMapping(value = "/queryModelInfo")
    public Result queryModelInfo(@RequestBody ModelVO query) {
        if (CheckVariable.isEmpty(query.getCreator())) {
            return Result.error("用户id不能为空");
        }

        // 查询发起人信息
        SysUser sysUser = sysUserMapper.queryByName(query.getCreatorName());
        if (CheckVariable.isEmpty(sysUser)) {
            return Result.error("未查询到用户信息");
        }

        // 获取用户相关的模型ID集合
        LambdaQueryWrapper<TModelActivity> activityWrapper = new LambdaQueryWrapper<>();
        activityWrapper.eq(TModelActivity::getFqrDeptId, sysUser.getDeptid())
                .or().eq(TModelActivity::getToDeptId, sysUser.getDeptid());
        List<TModelActivity> activityList = tModelActivityService.list(activityWrapper);
        Set<String> modelIds = new HashSet<>();
        if (!CheckVariable.isEmpty(activityList)) {
            modelIds = activityList.stream()
                    .map(TModelActivity::getModelId)
                    .collect(Collectors.toSet());
        }
        query.setIds(modelIds);

        // 查询模型分页数据
        IPage<ModelVO> modelVOIPage = tModelActivityService.modelPageList(query);
//
//        //看板风险预警临时查询所有数据
//        List<Map<String, Object>> modelListYJ = new ArrayList<>();
//        IPage<ModelVO> modelResult = tModelActivityService.getDataForYJ();
//        ArrayList<Object> arrayList = new ArrayList<>();
//        for (ModelVO record : modelResult.getRecords()) {
//            Map<String, Object> modelInfoYJ = new HashMap<>();
//            int result = getResult(record.getId());
//            modelInfoYJ.put("modelType", record.getCateName()); // 模型类别
//            modelInfoYJ.put("modelName", record.getName());     // 预警名称
//            modelInfoYJ.put("modelNum", result); // 问题数量
//            modelInfoYJ.put("modelStatus", record.getAppStatus()); // 预警状态
//
//            modelListYJ.add(modelInfoYJ);
//        }


        // 处理返回结果列表
        List<Map<String, Object>> modelList = new ArrayList<>();
        if (!CheckVariable.isEmpty(modelVOIPage.getRecords())) {
            for (ModelVO modelVO : modelVOIPage.getRecords()) {
                Map<String, Object> modelInfo = new HashMap<>();

                // 查询该模型最新一次运行记录
                LambdaQueryWrapper<IssueManage> lw = new LambdaQueryWrapper<>();
                lw.eq(IssueManage::getModelId, modelVO.getId())
                        .orderByDesc(IssueManage::getStartDate)
                        .last("limit 1");
                IssueManage issueManage = issueManageMapper.selectOne(lw);

                // 设置需要返回的字段
                modelInfo.put("modelType", modelVO.getCateName()); // 模型类别
                modelInfo.put("modelName", modelVO.getName());     // 预警名称
                modelInfo.put("modelNum", issueManage != null ? issueManage.getIssueNum() : 0); // 问题数量
                modelInfo.put("modelStatus", modelVO.getAppStatus()); // 预警状态

                modelList.add(modelInfo);
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("total", modelVOIPage.getTotal());
        result.put("pages", modelVOIPage.getPages());
        result.put("current", modelVOIPage.getCurrent());
        result.put("size", modelVOIPage.getSize());
        result.put("records", modelList);

        return Result.ok(result);
    }

    private Integer getResult(String modelId) {
        TModelRunRecord record = tModelRunRecordMapper.selectOne(
                new LambdaQueryWrapper<TModelRunRecord>()
                        .eq(TModelRunRecord::getModelid, modelId)
                        .eq(TModelRunRecord::getRuntype, "01")
                        .eq(TModelRunRecord::getRunstatus, "01")
                        .eq(TModelRunRecord::getRunprocess, "5")
                        .orderByDesc(TModelRunRecord::getEndtime)
                        .last("limit 1")
        );
        if (record == null) {
            return 0;
        }
        String table = record.getResulttable();
        String resultColumns = record.getResultcolumns();
        List<ModelColumnInfo> modelColumnInfoList = JSON.parseArray(resultColumns, ModelColumnInfo.class);
        List<String> groupColumns = groupRule.getOrDefault(modelId, new ArrayList<>());
        String sql = "";
        String sqlNum1 = "";
        String sqlNum2 = "";
        if (CollectionUtil.isEmpty(groupColumns)) {
            List<String> columns = modelColumnInfoList.stream().map(ModelColumnInfo::getEnname).collect(Collectors.toList());
            sql = "select " + String.join(",", columns)  + " from DIMENRESULT." + table;
            sqlNum1 = "select count (*)" + " from DIMENRESULT." + table;
        }else {
            List<String> columns = groupColumns.stream().map(e->modelColumnInfoList.stream().filter(item->item.getCnname().equals(e)).findFirst().map(ModelColumnInfo::getEnname).orElse(e)).collect(Collectors.toList());
            sql = "select distinct " + String.join(",", columns)  + " from DIMENRESULT." + table;
            sqlNum2 = "select count(*) from ( select  distinct " + String.join(",", columns)  + " from DIMENRESULT." + table + ")";
        }

        List<LinkedHashMap<String, Object>> dataList = reportMapper.getResultList(sql);
        int size = dataList.size();
        return size;
    }

    public static Map<String,List<String>> groupRule = new HashMap<String,List<String>>(){{
//        投标人一年内投标20次以上并且从未中标 投标年份、企业名称、投标数量
        put("7854D0EDF1BBB2112189E3EDC818AE23", CollectionUtil.newArrayList("投标年份", "企业名称", "投标数量"));
//        同一项目中，不同投标人使用同一台电脑（MAC地址、硬盘序列号等相同）项目名称、标段名称、制作投标文件mac码、同一标段使用同一MAC码的单位数量
        put("61FE6CD23093B2111BBC63261B804E3A", CollectionUtil.newArrayList("项目名称", "标段名称", "制作投标文件mac码", "同一标段使用同一MAC码的单位数量"));
//        同一项目中，不同投标人使用同一个IP地址上传或解密投标文件  项目名称、标段名称、使用同一IP地址上传文件的单位数量、招标文件上传IP地址
        put("483497EF3093B211249FAC81AE10F762", CollectionUtil.newArrayList("项目名称", "标段名称", "使用同一IP地址上传文件的单位数量", "招标文件上传IP地址"));
//        同一项目中，不同投标人的联系人、电话相同  投标联系人、投标联系人电话、组合数量、项目名称、标段名称、招标公告标题、中标人
        put("9D9B41063193B2119B94AA4EE543D732", CollectionUtil.newArrayList("投标联系人", "投标联系人电话", "组合数量", "项目名称", "标段名称", "招标公告标题"));
//        同一项目中，不同投标单位的地址相同   项目名称、标段名称、招标公告标题、单位注册地址、组合数量
        put("6E9B814928B0B21128BBBE8B07113612", CollectionUtil.newArrayList("项目名称", "标段名称", "招标公告标题", "单位注册地址", "组合数量"));
//        招标代理与中标人异常关联   企业、招标代理单位名称、特定代理的投标次数、特定代理的中标次数、特定代理下的中标率、投标次数、中标次数、中标率、概率差值
        put("84265AEA4297B211D99FF5FE89F76C56", CollectionUtil.newArrayList("企业名称","招标代理单位名称","特定代理的投标次数","特定代理的中标次数","特定代理下的中标率","投标次数","中标次数","中标率","概率差值"));
        //不同投标人一年内共同投标15次以上，并且合计中标5次以上     年份、组合投标企业名称1、组合投标企业名称2、组合投标企业名称3、组合投标次数、组合中标次数
        put("26B8693853BBB211E1A5C99A7FE7323F", CollectionUtil.newArrayList("年份", "组合投标次数", "组合投标企业名称1", "组合投标企业名称2","组合投标企业名称3","组合中标次数"));

    }};


    /**
     * 获取项目状态统计
     * @return
     */
    @GetMapping("/getCountProjectStatus")
    public Result<?> getCountProjectStatus() {
        return Result.ok(projectService.getCountProjectStatus());
    }

    /**
     * 获取总投资金额
     * @return
     */
    @GetMapping("/getCountInvestment")
    public Result<?> getCountInvestment() {
        return Result.ok(projectService.getCountInvestment());
    }

    /**
     * 获取项目类型统计
     * @return
     */
    @GetMapping("/getCountProjectType")
    public Result<?> getCountProjectType() {
        return Result.ok(projectService.getCountProjectType());
    }

    // 查询省交通重点工程 项目名称，项目进度
    @GetMapping("/progress")
    public Result<List<Map<String, Object>>> getProjectProgressList(String PROTYPE) {
        List<Map<String, Object>> progressList = projectService.getProjectProgressList(PROTYPE);
        for (Map<String, Object> progress : progressList) {
            progress.put("项目编号", progress.get("xmbh"));
            progress.put("项目名称", progress.get("xmmc"));
            progress.put("项目总投资", progress.get("ztz"));
            progress.put("项目已完成投资", progress.get("ywc"));

            if (progress.get("ztz") != null && progress.get("ywc") != null) {
                Number ztz = toNumber(progress.get("ztz"));
                double ztzValue = ztz.doubleValue();

                Number ywc = toNumber(progress.get("ywc"));
                double ywcV = ywc.doubleValue();
                double ywcValue =  ywcV / 10000;

                double value = ywcValue / ztzValue;

//                BigDecimal v1 = BigDecimal.valueOf(ztzValue);
//                BigDecimal v2 = BigDecimal.valueOf(ywcValue);
//
//                BigDecimal multiply = v2.multiply(BigDecimal.valueOf(100).valueOf(10000));
//                BigDecimal retio = v1.divide(multiply, 2, RoundingMode.HALF_UP);
                progress.put("投资进度", value);
            }else {
                progress.put("投资进度", 0);
            }

//            progress.put("项目进度", progress.get("xmjd"));
            progress.remove("xmbh");
            progress.remove("xmmc");
//            progress.remove("xmjd");
            progress.remove("ztz");
            progress.remove("ywc");
        }
        return Result.ok(progressList);
    }

    // 查询项目详情
    @GetMapping("/detail")
    public Result<List<Map<String, Object>>> getProjectDetail(@RequestParam("projectName") String projectName) throws IllegalAccessException {

        // 获取项目详情实体类
        ProjectOverviewDTO projectDetail = null;
        try {
            projectDetail = projectService.getProjectDetail(projectName);
        } catch (Exception e) {
            Map<String, Object> contentMap = new HashMap<>();
            contentMap.put("项目名称", null);
            contentMap.put("管理类型", null);
            contentMap.put("建设状态", null);
            contentMap.put("总投资", null);
            contentMap.put("建设标准", null);
            contentMap.put("规模（公里）", null);
            contentMap.put("建设周期（年）", null);
            contentMap.put("开工日期", null);
            contentMap.put("计划竣工日期", null);
            contentMap.put("设计时速（千米/小时）", null);
            contentMap.put("计划完工时间", null);
            contentMap.put("标段总数",null);
            contentMap.put("已完成投资额(亿)",null);
            return Result.ok(contentMap);
        }
        // 先判断项目是否存在，避免空指针
        if (projectDetail == null) {
            return Result.error(404, "未找到对应项目信息");
        }

        Map<String, Object> contentMap = new HashMap<>();
        contentMap.put("项目名称", projectDetail.getProjectName());
        contentMap.put("管理类型", projectDetail.getManagementType());
        contentMap.put("建设状态", projectDetail.getConstructionStatus());
        contentMap.put("总投资", projectDetail.getTotalInvestment());
        contentMap.put("建设标准", projectDetail.getConstructionStandard());
        contentMap.put("规模（公里）", projectDetail.getProjectSize());
        contentMap.put("建设周期（年）", projectDetail.getConstructionCycle());
        contentMap.put("开工日期", projectDetail.getStartDate());
        contentMap.put("计划竣工日期", projectDetail.getPlanFinishDate());
        contentMap.put("设计时速（千米/小时）", projectDetail.getDesignSpeed());
        contentMap.put("计划完工时间", projectDetail.getPlanCompletionTime());
        contentMap.put("实施主体", projectDetail.getUnit());

        String projectId = iZtbProjectService.getZtbProjectIdByProjectName(projectDetail.getProjectName());
        Integer bdNum = projectService.getBdNum(projectId);
        contentMap.put("标段总数",bdNum);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        SimpleDateFormat parser = new SimpleDateFormat("dd-M月 -yy hh.mm.ss.SSSSSSSSS a");

        try {

            String startDateStr = projectDetail.getStartDate();
            if (startDateStr != null && !startDateStr.isEmpty()) {
                Date startDate = parser.parse(startDateStr);
                contentMap.put("开工日期", sdf.format(startDate));
            } else {
                contentMap.put("开工日期", "");
            }


            String planFinishDateStr = projectDetail.getPlanFinishDate();
            if (planFinishDateStr != null && !planFinishDateStr.isEmpty()) {
                Date planFinishDate = parser.parse(planFinishDateStr);
                contentMap.put("计划竣工日期", sdf.format(planFinishDate));
            } else {
                contentMap.put("计划竣工日期", "");
            }


            String planCompletionTimeStr = projectDetail.getPlanCompletionTime();
            if (planCompletionTimeStr != null && !planCompletionTimeStr.isEmpty()) {
                Date planCompletionTime = parser.parse(planCompletionTimeStr);
                contentMap.put("计划完工时间", sdf.format(planCompletionTime));
            } else {
                contentMap.put("计划完工时间", "");
            }

        } catch (Exception e) {
            e.printStackTrace();
            contentMap.put("开工日期", projectDetail.getStartDate() != null ? projectDetail.getStartDate() : "日期解析失败");
            contentMap.put("计划竣工日期", projectDetail.getPlanFinishDate() != null ? projectDetail.getPlanFinishDate() : "日期解析失败");
            contentMap.put("计划完工时间", projectDetail.getPlanCompletionTime() != null ? projectDetail.getPlanCompletionTime() : "日期解析失败");
        }

        return Result.ok(contentMap);
    }
}
